use std::sync::{Arc, Mutex};
use std::thread::sleep;
use tokio;
use tokio::time::{interval, Duration};

pub struct Scheduled {
    // 间隔时间，毫秒级别
    space_time: u64,
    // 是否一次任务
    if_once: bool,
    //
    start_time: u64,
    //
    end_time: u64,
    // 结束任务
    if_finish: Arc<Mutex<bool>>,

}

impl Scheduled {
    pub fn build(space_time: u64,
                 if_once: bool, ) -> Self {
        return Scheduled {
            space_time,
            if_once,
            start_time: 0,
            end_time: 0,
            if_finish: Arc::new(Mutex::new(false)),
        };
    }

    pub fn time_ling(&mut self, start_time: u64, end_time: u64) -> &Self {
        self.start_time = start_time;
        self.end_time = end_time;
        return self;
    }


    pub async fn start_build(&self, f: fn(u64)) {
        let mut interval = interval(Duration::from_secs(self.space_time));
        let start_time = self.start_time;
        let end_time = self.end_time;
        let space_time = self.space_time;
        let if_finish = self.if_finish.clone();
        tokio::spawn(async move {
            if start_time == end_time {
                let mut temp: u64 = 0;
                loop {
                    if *if_finish.lock().unwrap() { break; };
                    interval.tick().await;
                    temp += 1;
                    f(space_time * temp);
                }
            } else {
                for temp in (end_time..start_time).rev() {
                    interval.tick().await;
                    f(temp);
                }
            }
        });
    }

    pub fn finished(&self) {
        let mut if_finish = self.if_finish.lock().unwrap();
        *if_finish = true;
    }
}

/* 延时执行的任务 */
pub async fn post_deylay(f: fn(), mills: u64) {
    tokio::spawn(async move {
        tokio::time::sleep(Duration::from_millis(mills)).await;
        f()
    });
}











